package org.com.curry.lee.utils.algorithm.algorithm.impl;


import org.com.curry.lee.annotation.Strategy;
import org.com.curry.lee.constant.StrategyConstants;
import org.com.curry.lee.utils.algorithm.algorithm.IDrawAlgorithm;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Component;

import java.net.URL;
import java.util.TreeMap;
import java.util.Vector;

import static org.opencv.core.CvType.CV_8U;
import static org.opencv.imgcodecs.Imgcodecs.imread;
import static org.opencv.imgproc.Imgproc.MORPH_RECT;

@Component("opencvAlgorithm")
@Strategy(strategyMode = StrategyConstants.StrategyMode.OPENCV)
public class OpencvAlgorithm implements IDrawAlgorithm {
    @Override
    public String messageDraw(String photoPath) throws Exception{
        URL url = ClassLoader.getSystemResource("lib/opencv_java455.dll");
        System.load(url.getPath());
        Mat img = imread("C:\\Users\\lenovo\\Desktop\\h\\2.png", 1);
        if (img.empty()){
            throw new Exception("image is empty!");
        }
        Mat srcImage2 = new Mat();
        Mat srcImage3 = new Mat();
        Mat srcImage4 = new Mat();
        Mat srcImage5 = new Mat();
        //图片变成灰度图片
        Imgproc.cvtColor(img, srcImage2, Imgproc.COLOR_RGB2GRAY);
//        Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\test\\1.png",srcImage2);
        //图片二值化
        Imgproc.adaptiveThreshold(srcImage2, srcImage3, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 255, 1);
//        Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\test\\2.png",srcImage3);
        Mat element = Imgproc.getStructuringElement(MORPH_RECT, new Size(1, 6));
        //腐蚀操作
        Imgproc.erode(srcImage3, srcImage4, element);
//        Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\test\\3.png",srcImage4);
        //膨胀操作
        Imgproc.dilate(srcImage4, srcImage5, element);
//        Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\test\\4.png",srcImage5);

//        //确定每张答题卡的ROI区域
//        Mat imag_ch1 = srcImage4.submat(new Rect(0, 0, 1000, 1000));
//        Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\test\\5.png",imag_ch1);
        //识别所有轮廓
        Vector<MatOfPoint> chapter1 = new Vector<>();
        Imgproc.findContours(srcImage5, chapter1, new Mat(), 2, 3);
        Mat result = new Mat(srcImage5.size(), CV_8U, new Scalar(255));
        Imgproc.drawContours(result, chapter1, -1, new Scalar(0), 2);

 //       Imgcodecs.imwrite("C:\\Users\\lenovo\\Desktop\\test\\5.png",result);

//        System.out.println("c"+chapter1.size());
        //new一个 矩形集合 用来装 轮廓
        Vector<RectComp> rectCompList = new Vector<>();
        for (int i=0; i < chapter1.size(); i++){
            Rect rm = Imgproc.boundingRect(chapter1.get(i));
            RectComp ti = new RectComp(rm);
            //把轮廓宽度区间在 50 - 80 范围内的轮廓装进矩形集合
            if (ti.getRm().width > 10 && ti.getRm().width < 85) {
                rectCompList.add(ti);
            }
        }
//        System.out.println(rectCompList.size());
//        rectCompList.forEach((rect) ->{
//            System.out.println(rect.getRm().area() + "--------" + rect.getRm().x +  "--------" + rect.getRm().height +  "--------" + rect.getRm().width);
//        });
        //按 X轴 对进行排序
        rectCompList.sort((o1,o2)->{
            if (o1.getRm().x > o2.getRm().x) {
                return 1;
            }
            if (o1.getRm().x == o2.getRm().x) {
                return 0;
            }
            if (o1.getRm().x < o2.getRm().x) {
                return -1;
            }
            return -1;
        });
//        //测试图片长宽xy作用的
//        rectCompList.forEach((rect) ->{
//            System.out.println(rect.getRm().area() + "--------" + rect.getRm().x +  "--------" + rect.getRm().height +  "--------" + rect.getRm().width+  "--------" + rect.getRm().y);
//        });
        TreeMap<Integer,String> listenAnswer = new TreeMap<Integer,String>();
        for (int no = 0;no<rectCompList.size();no++) {
            if (rectCompList.get(no).getRm().y <= 25) {
                listenAnswer.put(Integer.valueOf(no), "0");
            } else if(rectCompList.get(no).getRm().y > 25 && rectCompList.get(no).getRm().y <= 40){
                listenAnswer.put(Integer.valueOf(no), "1");
            }else if(rectCompList.get(no).getRm().y > 40 && rectCompList.get(no).getRm().y <= 55){
                listenAnswer.put(Integer.valueOf(no), "2");
            }else if(rectCompList.get(no).getRm().y > 55 && rectCompList.get(no).getRm().y <= 70){
                listenAnswer.put(Integer.valueOf(no), "3");
            }else if(rectCompList.get(no).getRm().y > 70 && rectCompList.get(no).getRm().y <= 85){
                listenAnswer.put(Integer.valueOf(no), "4");
            }else if(rectCompList.get(no).getRm().y > 85 && rectCompList.get(no).getRm().y <= 100){
                listenAnswer.put(Integer.valueOf(no), "5");
            }else if(rectCompList.get(no).getRm().y > 100 && rectCompList.get(no).getRm().y <= 115){
                listenAnswer.put(Integer.valueOf(no), "6");
            }else if(rectCompList.get(no).getRm().y > 115 && rectCompList.get(no).getRm().y <= 130){
                listenAnswer.put(Integer.valueOf(no), "7");
            }else if(rectCompList.get(no).getRm().y > 130 && rectCompList.get(no).getRm().y <= 145){
                listenAnswer.put(Integer.valueOf(no), "8");
            }else if(rectCompList.get(no).getRm().y > 145 ){
                listenAnswer.put(Integer.valueOf(no), "9");
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String l:listenAnswer.values()){
            stringBuilder.append(l);
        }
        String sb = stringBuilder.toString();
 //       System.out.println(sb);

        return sb;

    }
}
